package utils;

import entity.item;
import entity.taskInfo;
import entity.worker;
import pojo.TaskAssignment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDate;
import java.util.*;

public class DateHandle {
    private static  Logger logger = LoggerFactory.getLogger(DateHandle.class);

    private  List<worker> workers;
    private  List<taskInfo> taskInfos;
    private  List<item> items;
    private  WorkCalendar calendar;

    // 缓存映射
    private  Map<String, LocalDate> orderCodeToEarliestDate = new HashMap<>();
    private  Map<String, Integer> orderCodeToTotalCount = new HashMap<>();
    private  Map<String, item> itemIdToItem = new HashMap<>();
    private  Map<String, worker> workerMap = new HashMap<>();
    private  Map<String, List<worker>> workerGroupMap = new HashMap<>();

    public DateHandle(List<worker> workers, List<taskInfo> taskInfos, List<item> items) {
        this.workers = Objects.requireNonNull(workers, "workers cannot be null");
        this.taskInfos = Objects.requireNonNull(taskInfos, "taskInfos cannot be null");
        this.items = Objects.requireNonNull(items, "items cannot be null");
        this.calendar = new WorkCalendar();
        initMappings();
    }

    private void initMappings() {
        // 初始化工人映射
        for (worker w : workers) {
            workerMap.put(w.getEmployeeNo(), w);
            String groupName = w.getMdsWorkerGroupName();
            if (!workerGroupMap.containsKey(groupName)) {
                workerGroupMap.put(groupName, new ArrayList<>());
            }
            workerGroupMap.get(groupName).add(w);
        }

        // 初始化订单映射
        for (taskInfo task : taskInfos) {
            // 处理最早日期
            orderCodeToEarliestDate.merge(
                    task.getOrderCode(),
                    task.getDeadline(),
                    (existing, current) -> current.isBefore(existing) ? current : existing
            );

            // 处理总数
            orderCodeToTotalCount.merge(
                    task.getOrderCode(),
                    task.getTaskCount(),
                    Integer::sum
            );
        }

        // 初始化物料映射
        for (item item : items) {
            itemIdToItem.put(item.getItemId(), item);
        }
    }

    /**
     * 计算工人的月度工作量
     * @param workerNum 工人编号
     * @param year 年份
     * @param month 月份
     * @return 工作量（小时），如果未找到工人则返回-1
     */
    public double calculateWorkerWorkload(String workerNum, int year, int month) {
        validateDate(year, month);

        worker worker = workerMap.get(workerNum);
        if (worker == null) {
            logger.warn("未找到工人: {}", workerNum);
            return -1;
        }

        int workingDays = calculateWorkingDays(year, month);
        return worker.getEfficiencyCodfficient() * workingDays * 8;
    }

    /**
     * 计算制造单元的月度工作效率
     * @param workerGroupName 制造单元名称
     * @param year 年份
     * @param month 月份
     * @return 总工作量（小时）
     */
    public double calculateWorkcenterWorkload(String workerGroupName, int year, int month) {
        validateWorkerGroup(workerGroupName);
        validateDate(year, month);

        List<worker> groupWorkers = workerGroupMap.getOrDefault(workerGroupName, Collections.emptyList());
        double totalWorkload = 0.0;
        for (worker w : groupWorkers) {
            totalWorkload += calculateWorkerWorkload(w.getEmployeeNo(), year, month);
        }
        return totalWorkload;
    }

    /**
     * 返回某个制造单元合令后的任务列表
     * @param workcenterName 制造单元名称
     * @param month 月份
     * @return 排序后的任务分配列表
     */
    public List<TaskAssignment> handleTaskInfo(String workcenterName, int month) {
        validateWorkerGroup(workcenterName);
        Set<String> missingItems = new LinkedHashSet<>();
        Set<String> processedOrderCodes = new HashSet<>();
        List<TaskAssignment> taskAssignments = new ArrayList<>();

        for (taskInfo task : taskInfos) {
            item currentItem = itemIdToItem.get(task.getItemID());
            if (currentItem == null) {
                missingItems.add(task.getItemID());
                continue;
            }

            if (!currentItem.getWorkcenterName().equals("23_"+workcenterName)) {
                continue;
            }

            String code = task.getFlowOrderCode().equals("null") ? task.getOrderCode() : task.getFlowOrderCode();

            if (processedOrderCodes.contains(code)) {
                continue;
            }
            processedOrderCodes.add(code);

            LocalDate deadline = orderCodeToEarliestDate.get(code);
            if (deadline == null || deadline.getMonthValue() != month) {
                continue;
            }

            Integer totalQuantity = orderCodeToTotalCount.getOrDefault(code, 0);

            taskAssignments.add(new TaskAssignment(
                    task.getItemID(),
                    task.getOrderCode(),
                    task.getFlowOrderCode(),
                    task.getItemName(),
                    currentItem.getItemDifficulty(),
                    currentItem.getWorkcenterName(),
                    totalQuantity,
                    currentItem.getPreCycle(),
                    currentItem.getMakeCycle(),
                    deadline
            ));
        }

        if (!missingItems.isEmpty()) {
            logger.warn("未找到的物料数量: {}", missingItems.size());
            logger.debug("未找到的物料清单: {}", missingItems);
        }

        taskAssignments.sort(Comparator.comparing(TaskAssignment::getDeadline));
        return taskAssignments;
    }

    /**
     * 计算指定月份的工作天数
     */
    public int calculateWorkingDays(int year, int month) {
        LocalDate firstDayOfMonth = LocalDate.of(year, month, 1);
        LocalDate lastDayOfMonth = firstDayOfMonth.withDayOfMonth(firstDayOfMonth.lengthOfMonth());

        int workingDays = 0;
        LocalDate currentDate = firstDayOfMonth;

        while (!currentDate.isAfter(lastDayOfMonth)) {
            if (calendar.isWorkDay(currentDate) == 1) {
                workingDays++;
            }
            currentDate = currentDate.plusDays(1);
        }

        return workingDays;
    }

    /**
     * 验证日期参数
     */
    private void validateDate(int year, int month) {
        if (month < 1 || month > 12) {
            throw new IllegalArgumentException("月份必须在1-12之间");
        }
        if (year < 2000 || year > 2100) {
            throw new IllegalArgumentException("年份必须在2000-2100之间");
        }
    }

    /**
     * 验证制造单元名称
     */
    private void validateWorkerGroup(String workerGroupName) {
        if (workerGroupName == null || workerGroupName.trim().isEmpty()) {
            throw new IllegalArgumentException("制造单元名称不能为空");
        }
    }
}
